package com.example.config;

import com.example.interceptor.JwtInterceptor;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 注册拦截器
 * <p>
 * addPathPatterns（添加需要拦截的路径）
 * 作用：
 * 设置需要拦截的请求范围。
 * 在这个范围内的请求会触发拦截器逻辑。
 * <p></p>
 * excludePathPatterns（从拦截范围内排除路径）
 * 作用：
 * 明确指定某些路径不需要被拦截，直接放行。
 * 通常用于指定一些无需校验的请求，如：登录页面、静态资源（图片、CSS、JS）等。
 * <p></p>
 * excludePathPatterns 的优先级高于 addPathPatterns：
 * 先看请求路径是否在 excludePathPatterns 中：
 * 如果是，不执行拦截器逻辑，直接放行；
 * 如果不是，再去看是否在 addPathPatterns 中定义的范围内：
 * 在范围内 → 执行拦截器逻辑
 * 不在范围内 → 不执行拦截器逻辑（直接放行）
 */

/**
 * addPathPatterns（添加需要拦截的路径）
 * 作用：
 * 设置需要拦截的请求范围。
 * 在这个范围内的请求会触发拦截器逻辑。
 * <p></p>
 * excludePathPatterns（从拦截范围内排除路径）
 * 作用：
 * 明确指定某些路径不需要被拦截，直接放行。
 * 通常用于指定一些无需校验的请求，如：登录页面、静态资源（图片、CSS、JS）等。
 * <p></p>
 * excludePathPatterns 的优先级高于 addPathPatterns：
 *  先看请求路径是否在 excludePathPatterns 中：
 *      如果是，不执行拦截器逻辑，直接放行；
 *      如果不是，再去看是否在 addPathPatterns 中定义的范围内：
 *          在范围内 → 执行拦截器逻辑
 *          不在范围内 → 不执行拦截器逻辑（直接放行）
 */

/**
 * 注册拦截器的作用：判断是否触发拦截器
 * 在拦截 addPathPatterns 中但不在放行 excludePathPatterns 中会被拦截
 * 在拦截 addPathPatterns 中但也在放行 excludePathPatterns 中会被放行
 * 不在拦截 addPathPatterns 会被放行
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Resource
    private JwtInterceptor jwtInterceptor;

    /**
     * addPathPatterns 和 excludePathPatterns 控制的是拦截器的执行范围（拦截器是否会触发）；
     * 而拦截器内部逻辑的判断（如 url.contains("/login")）则控制的是具体的放行与否。
     * 这两者并不冲突，而是两道不同层次的控制：
     * 路径配置控制整体拦截范围；
     * 内部逻辑则灵活控制每个请求具体的行为（登录状态、权限检查等）。
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor)
                // 第一种方式：拦截所有，放行指定接口
                /**
                // 拦截所有
                .addPathPatterns("/**")
                // 接口放行
                .excludePathPatterns(
                        "/auth/login",
                        "/Cookie/**",
                        "/Session/**",
                        "/Token/**",
                        "/JWT/**"
                 */
                // 第二种方式
                // 拦截指定接口
                .addPathPatterns("/auth/**")
                // 放行指定接口下的子指定接口
                .excludePathPatterns(
                        "/auth/login"
                );
    }
}
